using System.Linq;
using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Actions;
using CardPlay.Model.GameModel.Presentation;
using CardPlay.Model.Layout;

namespace CardPlay.DemoPack.Games.BeleaguredCastleVariants
{
    [Game("5B615FAF-C036-4DE8-9A88-3F5D395BF35E", LevelOfDifficulty.Medium, LevelOfSkill.MostlySkill, DurationOfPlay.Within5To10Minutes, Family = FamilyName)]
    public class Chessboard : BeleagueredCastle
    {
        public const string Tableau9 = StandardPileNames.PrefixForTableau + "9";
        public const string Tableau10 = StandardPileNames.PrefixForTableau + "10";

        public Chessboard()
        {
            TotalTableaus = 10;
            TableauBuildSequence = CardFaceSequence.SameSuitAdjacentRank;
        }

        public override ILayoutSite CreatePresentation(IPresentationContext presentation)
        {
            var root = presentation.CreateGridLayout(1, 2);

            {
                var foundationStyle = presentation.StyleForRepeatedRankFoundation(this, FoundationBaseRank, TotalDecks);
                foundationStyle.UpdateBaseCues = UpdateFoundationHints;

                var foundations = presentation.CreateRowLayout(HorizontalAlignment.Center);
                root.Add(presentation.AddPiles(foundations, NamesOfFoundations, foundationStyle));

                foundations.Margin = new MarginSize(0, 0, 0, presentation.Metrics.MaxSpacingDown);
            }

            {
                var tableau = presentation.CreateRowLayout(HorizontalAlignment.Center);
                root.Add(presentation.AddTableauPiles(this, tableau));
            }

            return root;
        }

        protected override void PrepareDealScript(DealScript script)
        {
            script.Deal("6 up").To(Tableau1);
            script.Deal("6 up").To(Tableau2);
            script.Deal("5 up").To(Tableau3);
            script.Deal("5 up").To(Tableau4);
            script.Deal("5 up").To(Tableau5);
            script.Deal("5 up").To(Tableau6);
            script.Deal("5 up").To(Tableau7);
            script.Deal("5 up").To(Tableau8);
            script.Deal("5 up").To(Tableau9);
            script.Deal("5 up").To(Tableau10);
        }

        protected override bool AllowedToPickupAtTableau(RemovePileAction action)
        {
            return action.IsActingOnFaceUpTopCard();
        }

        protected override bool AllowedToBuildFoundation(MovePileAction action)
        {
            return PilesNamed(AnyFoundation).All(pile => pile.IsEmpty) 
                ? action.TargetPile.Location.Matches(Foundation1) 
                : base.AllowedToBuildFoundation(action);
        }

        protected override void OnTransactionEnding()
        {
            base.OnTransactionEnding();

            var rankOfFirstFoundation = RankOfFirstFoundation;
            if (rankOfFirstFoundation != null) FoundationBaseRank = rankOfFirstFoundation.Value;
        }

        private Rank? RankOfFirstFoundation
        {
            get
            {
                var bottomCardOfFirstFoundation = CardAt(new PartLocation(Foundation1, 0));
                return bottomCardOfFirstFoundation == null ? default(Rank?) : bottomCardOfFirstFoundation.Rank;
            }
        }

        private void UpdateFoundationHints(CardPile pile, BaseCues baseCues)
        {
            baseCues.Rank = RankOfFirstFoundation;
            baseCues.SetFoundationSuitCue(this, AnyFoundation);
        }
    }
}